
import { assetManager, instantiate, Node, Prefab, SpriteFrame, SpriteAtlas, AudioClip, JsonAsset } from "cc";
import { PoolManager } from "./PoolManager";

/**
 * copyright (c) 2017-2023 厦门风领科技有限公司
 * http://www.fenglinghudong.com/
 * 
 * 资源管理类
 * chengen
 * 2023-08-24 11:52:35
 */

export class ResManager {
    /** 资源管理 单例 **/
    private static _instance: ResManager;
    /** 音频资源数组 */
    public _clipMap = {};
    /** 图集资源数组 */
    private _atlasMap = {};
    /** 配置信息数组 */
    public _jsonAssetMap = {};
    /** bundle包数组 */
    public _loadStemp = null;
    private _spriteFramesMap = {};
    _totalTime = 0


    static get instance() {
        if (this._instance) {
            return this._instance;
        }

        this._instance = new ResManager();
        return this._instance;
    }

    /**加载bundle资源 */
    public async loadBundle(name: string): Promise<void> {
        return new Promise<void>((resolve, reject) => {
            assetManager.loadBundle(name, (err: any, bundle: any) => {
                if (err) {
                    console.error("Bundle " + name + " load error, error==", err)
                } else {
                    resolve && resolve();
                }
            })
        })
    }

    public async loadRes(name: string, type: any): Promise<void> {
        return new Promise<void>((resolve, reject) => {
            let bundle = assetManager.getBundle(name);
            bundle.loadDir(type.path, type.type, (finished: number, total: number) => {

            }, (err: any, assets: any[]) => {
                if (err) {
                    console.error(" loadRes Error ", err);
                    resolve && resolve();
                }
                let asset: any
                if (type.type == Prefab) {
                    for (let i = 0; i < assets.length; i++) {
                        asset = assets[i];
                        PoolManager.instance.setPrefab(asset.data.name, asset);
                    }
                }
                if (type.type == AudioClip) {
                    for (let i = 0; i < assets.length; i++) {
                        asset = assets[i];
                        if (!this._clipMap[asset.name]) this._clipMap[asset.name] = asset
                    }
                }
                if (type.type == SpriteAtlas) {
                    for (let i = 0; i < assets.length; i++) {
                        asset = assets[i];
                        if (!this._atlasMap[asset.name]) this._atlasMap[asset.name] = asset
                    }
                }
                if (type.type == SpriteFrame) {
                    for (let i = 0; i < assets.length; i++) {
                        asset = assets[i];
                        if (!this._spriteFramesMap[asset.name]) this._spriteFramesMap[asset.name] = asset
                    }
                }
                if (type.type == JsonAsset) {
                    for (let i = 0; i < assets.length; i++) {
                        asset = assets[i];
                        if (!this._jsonAssetMap[asset.name]) this._jsonAssetMap[asset.name] = asset.json
                    }
                }
                resolve && resolve();
            })
        })
    }

    public async loadPrefab(info): Promise<void> {
        return new Promise<void>((resolve, reject) => {
            let bundle = assetManager.getBundle(info.bundle);
            bundle.load(info.path + info.name, function (err, Prefab: Prefab) {
                if (err) {
                    console.error("Error info===", err);
                    resolve && resolve();
                }
                PoolManager.instance.setPrefab(info.name, Prefab);
                resolve && resolve();
            })
        }
        )
    }

    /* get the prefabs from prefab config */
    public async getPrefab(prefabPath: any, parent?: Node) {

        if (PoolManager.instance.getPrefab(prefabPath.name)) {
            return PoolManager.instance.getNode(prefabPath.name, parent)
        }
        await this.loadPrefab(prefabPath)
        return PoolManager.instance.getNode(prefabPath.name, parent)
    }

    public async preloadRes(name: string, count: number): Promise<void> {
        return new Promise<void>((resolve, reject) => {
            let pre = PoolManager.instance.getPrefab(name);
            for (let i = 0; i < count; i++) {
                PoolManager.instance.putNode(instantiate(pre));
            }
            resolve && resolve();
        })
    }
    public getAtlas(name: string): SpriteAtlas {
        return this._atlasMap[name];
    }

    /**
     * 获取图片
     * @param name 图片名字
     * @returns spriteFrame 精灵帧图片
     */
    public getSpriteFrame(name: string): SpriteFrame {
        return this._spriteFramesMap[name];
    }

    public getClip(name: string) {
        return this._clipMap[name];
    }


    /* get the json from preloade */
    public getJson(name: string) {
        return this._jsonAssetMap[name];
    }
}

(window as any).ResManager = ResManager;